/*
 * GToe: Gtk+ TicTacToe
 * core.c: gtoe core
 *
 * Copyright (C) 2010 Dani El-Soufi <danisoufi@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "../include/info.h"
#include "../include/menu.h"
#include "../include/form.h"
#include "../include/matrix.h"
#include "../include/minimax.h"
#include "../include/player.h"
#include "../include/misc.h"

PLAYER *p1, *p2;
MATRIX **matrix;
WINDOW *window;

int recv_eof = 0;
int max_depth;

void new_game(void);
void quit(void);
void set_single_player_max_depth(int selection);
void new_single_player_game(void);
void new_two_player_game(void);
int game_check(void);

void
new_game(void)
{
    int selection = 0;
    int who_starts = 0;

    selected = gtoe_select_menu();

    p1 = new_player();
    p2 = new_player();

    if (selected == 1)
    {
        p1->name = get_pname(0);
        p2->name = "Algo";

        who_starts = who_starts_first();

        if (who_starts == 1)
        {
            p1->starts = 1;
            /* TODO: Print who starts first */
        }
        else if (who_starts == 2)
        {
            p2.starts = 1;
            /* TODO: Print who starts first */
        }
            new_single_player_game();
    }
    else if (selected == 2)
    {
        who_starts = who_starts_first();

        p1->name = get_pname(1);
        p2->name = get_pname(2);

        if (who_starts == 1)
        {
            p1->starts = 1;
            /* TODO: Print who starts first */
        }
        else if (who_starts == 2)
        {
            p2->starts = 1;
            /* TODO: Print who starts first */
        }

        new_two_player_game();
    }
    else if (selected == 3)
    {
        /* TODO: Initialize network game */
    }
}

int
main(int argc, char *argv[])
{
    parse_cmd_args(argc, argv);

    new_game();

    return 0;
}

void
quit(void)
{
    int i;

    unpost_menu(menu);
    free_menu(menu);

    for (i = 0; i < menu->nitems; ++i)
    {
    	free_item(item[i]);
    }

    if (field != NULL)
    {
       unpost_form(form);
       free_form(form);

       for(i = 0; i < form->maxfield; i++)
       {
          free_field(field[i]);
       }
       free(field);
    }

    free(item);
    delwin(window);

    endwin();
}

void
init_term(void)
{
    initscr();
    clear();
    noecho();
    cbreak();
    nl();
    keypad(stdscr, TRUE);
}

void
set_single_player_max_depth(int diff)
{
    if (diff == 1)
    {
        depth_max = 5;
    }
    else if (diff == 2)
    {
        depth_max = 6;
    }
    else if (diff == 3)
    {
        depth_max = 7;
    }
}

void
new_single_player_game(void)
{
    int winner = -1;
    int diff = select_difficulty_menu();

    set_single_player_max_depth(diff);

    matrix = new_matrix();

    if (p1->starts)
    {
        do
        {
            /* TODO: Show game board. Get human player's move */
            winner = game_check();

            if (winner == 1)
            {
                p1->wins++;
                p2->looses++;
                break;
            }
            else if (winner == 0)
            {
                break;
            }

            /* TODO: Show game board. Get AI's move */
            winner = game_check();

            if (winner == 2)
            {
                p2->wins++;
                p1->looses++;
                break;
            }
            else if (winner == 0)
            {
                break;
            }
        }
        while (winner == -1);
    }
    else if (p2->starts)
    {
        do
        {
            /* TODO: Show game board. Get AI's move */
            winner = game_check();

            if (winner == 2)
            {
                p2->wins++;
                p1->looses++;
                break;
            }
            else if (winner == 0)
            {
                break;
            }

            /* TODO: Show game board. Get human player's move */
            winner = game_check();

            if (winner == 1)
            {
                p1->wins++;
                p2->looses++;
                break;
            }
            else if (winner == 0)
            {
                break;
            }
        }
        while (winner == -1);
    }

    if (winner == 1)
    {
        /* TODO: Show the winner of the game.*/
    }
    else if (winner == 2)
    {
        /* TODO: Show the winner of the game.*/
    }
    else if (winner == 0)
    {
        /* TODO: Show "No one won" */
    }

    /* TODO: Play again question */
}

void
new_two_player_game(void)
{
    int winner = -1;
    
    matrix = new_matrix();

    if (p1->starts)
    {
        do
        {
            /* TODO: Show game board. Get player 1 move */
            winner = game_check();

            if (winner == 1)
            {
                p1->wins++;
                p2->looses++;
                break;
            }
            else if (winner == 0)
            {
                break;
            }

            /* TODO: Show game board. Get player 2 move */
            winner = game_check(matrix);

            if (winner == 2)
            {
                p2->wins++;
                p1->looses++;
                break;
            }
            else if (winner == 0)
            {
                break;
            }
        }
        while (winner == -1);
    }
    else if (p2->starts)
    {
        do
        {
            /* TODO: Show game board. Get player 2 move */
            winner = game_check();

            if (winner == 2)
            {
                p2->wins++;
                p1->looses++;
                break;
            }
            else if (winner == 0)
            {
                break;
            }

            /* TODO: Show game board. Get player 2 move */
            winner = game_check();

            if (winner == 1)
            {
                p1->wins++;
                p2->looses++;
                break;
            }
            else if (winner == 0)
            {
                break;
            }
        }
        while (winner == -1);
    }

    if (winner == 1)
    {
        /* TODO: Show the winner of the game.*/
    }
    else if (winner == 2)
    {
        /* TODO: Show the winner of the game.*/
    }
    else if (winner == 0)
    {
        /* TODO: Show "No one won" */
    }

    /* TODO: Play again question */
}

int
game_check(void)
{
    int c, r, i, j;
    char s[] = {X, O};

    /* row */
    for (i = 0; i < 2; ++i)
    {
        for (c = 0; c < 3; ++c)
        {
            for (j = 0; j < 3; ++j)
            {
                if (matrix[c][j] != s[i])
                {
                    break;
                }
                else if (j == 2)
                {
                    if (s[i] == X)
                    {
                        return 1;
                    }
                    else
                    {
                        return 2;
                    }
                }
            }
        }

        /* collumn */
        for (r = 0; r < 3; ++r)
        {
            for (j = 0; j < 3; ++j)
            {
                if (matrix[j][r] != s[i])
                {
                    break;
                }
                else if (j == 2)
                {
                    if (s[i] == X)
                    {
                        return 1;
                    }
                    else
                    {
                        return 2;
                    }
                }
            }
        }

        /* diagonal */
        for (j = 0; j < 3; ++j)
        {
            if (board[j][j] != s[i])
            {
                break;
            }
            else if (j == 2)
            {
                if (s[i] == X)
                {
                    return 1;
                }
                else
                {
                    return 2;
                }
            }
        }

        /* opposite diagonal */
        for (j = 0; j < 3; ++j)
        {
            if (matrix[j][2 - j] != s[j])
            {
                break;
            }
            else if (j == 2)
            {
                if (s[i] == X)
                {
                    return 1;
                }
                else
                {
                    return 2;
                }
            }
        }
    }

    return 3;
}
